package ${basepackage}.config.druid;

import java.sql.SQLException;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.alibaba.druid.pool.DruidDataSource;

@Primary
@Configuration
@EnableTransactionManagement
public class DataSourceConfig {
  private Logger logger = LoggerFactory.getLogger(DataSourceConfig.class);

  @Value("${r'${spring.datasource.url}'}")
  private String dbUrl;

  @Value("${r'${spring.datasource.username}'}")
  private String username;

  @Value("${r'${spring.datasource.password}'}")
  private String password;

  @Value("${r'${spring.datasource.driver-class-name}'}")
  private String driverClassName;

  @Value("${r'${spring.datasource.initialSize}'}")
  private int initialSize;

  @Value("${r'${spring.datasource.minIdle}'}")
  private int minIdle;

  @Value("${r'${spring.datasource.maxActive}'}")
  private int maxActive;

  @Value("${r'${spring.datasource.maxWait}'}")
  private int maxWait;

  @Value("${r'${spring.datasource.timeBetweenEvictionRunsMillis}'}")
  private int timeBetweenEvictionRunsMillis;

  @Value("${r'${spring.datasource.minEvictableIdleTimeMillis}'}")
  private int minEvictableIdleTimeMillis;

  @Value("${r'${spring.datasource.validationQuery}'}")
  private String validationQuery;

  @Value("${r'${spring.datasource.testWhileIdle}'}")
  private boolean testWhileIdle;

  @Value("${r'${spring.datasource.testOnBorrow}'}")
  private boolean testOnBorrow;

  @Value("${r'${spring.datasource.testOnReturn}'}")
  private boolean testOnReturn;

  @Value("${r'${spring.datasource.poolPreparedStatements}'}")
  private boolean poolPreparedStatements;

  @Value("${r'${spring.datasource.maxPoolPreparedStatementPerConnectionSize}'}")
  private int maxPoolPreparedStatementPerConnectionSize;

  @Value("${r'${spring.datasource.filters}'}")
  private String filters;

  @Value("{spring.datasource.connectionProperties}'}")
  private String connectionProperties;

  @Bean
  @Primary
  public DataSource dataSource() {
    DruidDataSource datasource = new DruidDataSource();

    datasource.setUrl(this.dbUrl);
    datasource.setUsername(username);
    datasource.setPassword(password);
    datasource.setDriverClassName(driverClassName);

    datasource.setInitialSize(initialSize);
    datasource.setMinIdle(minIdle);
    datasource.setMaxActive(maxActive);
    datasource.setMaxWait(maxWait);
    datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
    datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
    datasource.setValidationQuery(validationQuery);
    datasource.setTestWhileIdle(testWhileIdle);
    datasource.setTestOnBorrow(testOnBorrow);
    datasource.setTestOnReturn(testOnReturn);
    datasource.setPoolPreparedStatements(poolPreparedStatements);
    datasource
        .setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
    try {
      datasource.setFilters(filters);
    } catch (SQLException e) {
      logger.error("druid configuration initialization filter", e);
    }
    datasource.setConnectionProperties(connectionProperties);
    return datasource;
  }
}
